home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / assign manager / assignwedge / source / stackcall.a < prev    next >
Text File  |  1996-04-07  |  3KB  |  141 lines

  1. **
  2. **    StackCall.a
  3. **
  4. **    Stack swap routines
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9.  
  10.     include "exec/types.i"
  11.     include "exec/tasks.i"
  12.     include "exec/memory.i"
  13.     include "exec/execbase.i"
  14.  
  15.     include "dos/dos.i"
  16.     include "dos/dosextens.i"
  17.  
  18. *----------------------------------------------------------------------
  19.  
  20. CALL    macro
  21.     xref    LVO\1
  22.     jsr    LVO\1(a6)
  23.     endm
  24.  
  25. *----------------------------------------------------------------------
  26.  
  27. ARG_SUCCESS    equ    4+5*4
  28. ARG_STACKSIZE    equ    ARG_SUCCESS+4
  29. ARG_ARGCOUNT    equ    ARG_STACKSIZE+4
  30. ARG_ROUTINE    equ    ARG_ARGCOUNT+4
  31. ARG_ARGS    equ    ARG_ROUTINE+4
  32.  
  33. TRUE        equ    1
  34. FALSE        equ    0
  35.  
  36. *----------------------------------------------------------------------
  37.  
  38.     csect    text,0,0,1,2
  39.  
  40. *----------------------------------------------------------------------
  41.  
  42.     xdef    StackCall
  43.  
  44.     ;    LONG __stdargs StackCall(    LONG *Success,
  45.     ;                    LONG StackSize,
  46.     ;                    LONG ArgCount,
  47.     ;                    LONG (* __stdargs Function)(...),
  48.     ;                    ...);
  49.     ;
  50.     ;    Calls a function with parameters on a newly-allocated
  51.     ;    stack. Caution: assumes all arguments are 32 bits wide.
  52.  
  53. StackCall:
  54.  
  55.     movem.l d2/d3/a2/a3/a6,-(sp)        ; Save registers
  56.  
  57.     move.l    ARG_STACKSIZE(sp),d0        ; Get desired stack size
  58.     add.l    #15+StackSwapStruct_SIZEOF,d0    ; Round to next...
  59.     and.l    #-16,d0             ; ...quad long word
  60.     move.l    d0,d2                ; Save it for later
  61.     move.l    #MEMF_PUBLIC,d1         ; Well?
  62.     move.l    SysBase(a4),a6            ; Get SysBase
  63.  
  64.     CALL    AllocMem            ; Allocate the memory
  65.     tst.l    d0                ; Successful?
  66.     beq.b    1$                ; Exit if not
  67.  
  68.     move.l    d0,a2                ; Remember base address
  69.  
  70.     add.l    #StackSwapStruct_SIZEOF,d0    ; Skip the header
  71.     move.l    d0,stk_Lower(a2)        ; Store the stack lower bound
  72.  
  73.     move.l    a2,a3                ; Get the base address
  74.     add.l    d2,a3                ; Add the allocation size
  75.     move.l    a3,stk_Upper(a2)        ; Store the stack upper bound
  76.  
  77.     move.l    ARG_ARGCOUNT(sp),d0        ; Get the number of arguments
  78.     beq.b    3$                ; Skip if none
  79.  
  80.     move.l    d0,d1
  81.     add.l    d1,d1                ; One long word per argument
  82.     add.l    d1,d1
  83.     addq.l    #4,d1                ; One for predecrement
  84.     sub.l    d1,a3                ; Pull it down
  85.  
  86.     subq.l    #1,d0                ; Subtract one for DBRA
  87.     lea.l    ARG_ARGS(sp),a0         ; Get the source argument list
  88.     move.l    a3,a1                ; Get the destination argument list
  89.  
  90. 2$    move.l    (a0)+,(a1)+            ; Copy the parameters
  91.     dbra    d0,2$                ; Loop until all is copied
  92.  
  93. 3$    move.l    a3,stk_Pointer(a2)        ; Store the new stack pointer
  94.  
  95.     move.l    ARG_ROUTINE(sp),a3        ; Get address of the routine to call
  96.  
  97.     move.l    a2,a0                ; Swap the stack
  98.     CALL    StackSwap
  99.  
  100.     jsr    (a3)                ; Call the routine
  101.     move.l    d0,d3                ; Save the result
  102.  
  103.     move.l    a2,a0                ; Swap the stack
  104.     CALL    StackSwap
  105.  
  106.     move.l    a2,a1                ; Get the base address
  107.     move.l    d2,d0                ; Get the allocation length
  108.     CALL    FreeMem             ; Free the memory
  109.  
  110.     move.l    ARG_SUCCESS(sp),a0        ; Flag as success
  111.     move.l    #TRUE,(a0)
  112.  
  113.     move.l    d3,d0                ; Return the result
  114.  
  115.     movem.l (sp)+,d2/d3/a2/a3/a6        ; Restore registers
  116.     rts
  117.  
  118. 1$    move.l    ARG_SUCCESS(sp),a0        ; Flag as failure
  119.     move.l    #FALSE,(a0)
  120.  
  121.     movem.l (sp)+,d2/d3/a2/a3/a6        ; Restore registers
  122.     rts
  123.  
  124. *----------------------------------------------------------------------
  125.  
  126.     dc.l    _BSSBAS
  127.     dc.l    _BSSLEN
  128.  
  129. *----------------------------------------------------------------------
  130.  
  131.     csect    __MERGED,data
  132.  
  133.     xref    SysBase
  134.  
  135.     xref    _BSSBAS
  136.     xref    _BSSLEN
  137.  
  138. *----------------------------------------------------------------------
  139.  
  140.     end
  141.